package cn.jbooter.restweb.autoconfigure.realms;

import java.util.Set;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import cn.jbooter.restweb.frame.api.AuthorizationInfoApi;

/**
 * 使用username和password的realm
 * @author hejian
 *
 */
public class UsernamePasswordRealm extends AuthorizingRealm{
	
	private static final Logger logger = LoggerFactory.getLogger(UsernamePasswordRealm.class);
	
	@Autowired
	private AuthorizationInfoApi authorizationInfoApi;

	/**
	 * 该realm使用在用户名和密码登录环境
	 */
	@Override  
    public boolean supports(AuthenticationToken token) {
        //仅支持UsernamePasswordToken类型的Token  
        return token instanceof UsernamePasswordToken;
    }  
	
	/**
	 * 获取授权信息
	 */
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        String loginname = (String) principals.getPrimaryPrincipal();
        logger.info(">>>>>> "+loginname+" AuthorizingRealm doGetAuthorizationInfo start");
        //角色信息
        Set<String> roles = authorizationInfoApi.findRolesByUserId(loginname);
        //查询权限
        Set<String> perms = authorizationInfoApi.findPermissionsByUserId(loginname);
        if(roles != null && roles.size() > 0) {
        	authorizationInfo.addRoles(roles);
        	//这里将角色也添加到权限字符串是为了shiro调用isPermited的方法也能判断角色
        	//同时也是为了方便前端的shiro权限判断的使用
        	authorizationInfo.addStringPermissions(roles);
        }
        if(perms != null && perms.size() > 0) {
       	 	authorizationInfo.addStringPermissions(perms);
        }
        
        logger.info("登录用户：" + loginname);
        logger.info("角色：" + roles);
        logger.info("权限：" + perms);
        logger.info("<<<<<< "+loginname+" AuthorizingRealm doGetAuthorizationInfo end");
        return authorizationInfo;  
	}

	/**
	 * 获取认证信息
	 * 注意:这里直接返回是因为登录认证逻辑必须在LoginController的subject.login方法调用前实现.故这里shiro只需返回认证登录成功
	 * 
	 */
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) throws AuthenticationException {
		UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
		String loginname = (String) token.getPrincipal();
		Object password = token.getCredentials();
		//简单的token中的密码和AuthenticationInfo中的密码是否相等来匹配
		AuthenticationInfo rs = new SimpleAuthenticationInfo(loginname ,password, getName());
		return rs;
	}

}
